//Copyright(c)[2025][AGIROS][TravoDDS] is licensed under Mulan PSL v2.
//
//You can use this software according to the terms and conditions of
//the Mulan PSL v2.You may obtain a copy of Mulan PSL v2 at :
//http://license.coscl.org.cn/MulanPSL2
//
//THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF
//ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO
//NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
//
//See the Mulan PSL v2 for more details.
#ifndef AGIDDS_DCPS_DOMAIN_DOMAINPARTICIPANT_H
#define AGIDDS_DCPS_DOMAIN_DOMAINPARTICIPANT_H

#include "dcps/publish/publisher.h"
#include "dcps/subscribe/subscriber.h"
#include "dcps/topic/contentfilteredtopic.h"
#include "dcps/topic/multitopic.h"
#include "dcps/listener/domainparticipantlistener.h"

AGIDDS_NAMESPACE_BEGIN

class Publisher;
class TypeSupport;
/**
 * @brief
 * DomainParticipant代表域中应用程序的本地成员资格。
 *
 * DomainParticipant表示应用程序在通信平面上的参与者，
 * 该通信平面将运行在同一组物理计算机上的应用程序彼此隔离。
 * 域建立一个虚拟网络，链接共享相同域ID的所有应用程序，
 * 并隔离它们来自在不同域上运行的应用程序。通过这种方式，
 * 几个独立的分布式应用程序可以在同一物理环境中共存
 * 网络之间没有干扰，甚至彼此都知道。
 *
 */
class DDS_DLL DomainParticipant : public virtual Entity {
public:
    /**
     * @brief 析构函数。
     */
    virtual ~DomainParticipant() = default;

    /**
     * 为此实例设置DomainParticipantQos。
     *
     * @param qos DomainParticipantQos
     */
	virtual ReturnCode_t set_qos(const DomainParticipantQos& qos) = 0;

    /**
     * 获取此实例的DomainParticipantQos设置。
     *
     * @return qos DomainParticipantQos。
     */
	virtual ReturnCode_t get_qos(DomainParticipantQos& qos) const = 0;

    /**
     * 在DomainParticipant中注册一个监听器。
     *
     * 监听器收到的通知取决于它注册时使用的状态掩码。
     *
     * 通过将监听器设置为NULL来执行监听器取消注册。
     *
     * @param listener 监听器句柄。
     * @param mask 定义将通知监听器的事件。
     */
	virtual ReturnCode_t set_listener(DomainParticipantListener* listener, const StatusMask& mask) = 0;

    /**
     * 获取此DomainParticipant的监听器。
     *
     * @return 监听器句柄。
     */
	virtual const DomainParticipantListener* get_listener() const = 0;

    /**
     * 在此参与者中创建发布者。
     * @param qos 发布者的QoS
     * @param listenerer 指向侦听器的指针。
     * @param mask 状态掩码。
     * @return 指向已创建发布者的指针。
     */
    virtual Publisher* create_publisher(const PublisherQos& qos, PublisherListener* listener, const StatusMask& mask) = 0;

    /**
     * 删除现有发布者。
     *
     * @param publisher 要删除的发布者句柄.
     * @return 如果发布者不属于此参与者，或者如果它有活动的数据写入器，
     * 则返回RETCODE_PRECONDITIONNOT_MET，如果正确删除了RETCODE_OK，否则返回RETCODE_ERROR。
     */
    virtual ReturnCode_t delete_publisher(Publisher*& publisher) = 0;

    /**
     * 在此参与者中创建订阅者。
     * @param qos 订阅者的QoS
     * @param listenerer 指向侦听器的指针。
     * @param mask 状态掩码。
     * @return 指向已创建订阅者的指针。
     */
    virtual Subscriber* create_subscriber(const SubscriberQos& qos, SubscriberListener* listener, const StatusMask& mask) = 0;

    /**
     * 删除现有订阅者。
     *
     * @param publisher 要删除的订阅者句柄.
     * @return 如果订阅者不属于此参与者，或者如果它有活动的数据写入器，
     * 则返回RETCODE_PRECONDITIONNOT_MET，如果正确删除了RETCODE_OK，否则返回RETCODE_ERROR。
     */
    virtual ReturnCode_t delete_subscriber(Subscriber*& subscriber) = 0;

    /**
     * 在此参与者中创建主题。
     *
     * @param topic_name 主题名.
     * @param type_name 主题的数据类型。
     * @param qos 主题的Qos.
     * @param listener 指向侦听器的指针。
     * @param mask StatusMask，保存侦听器响应的状态。
     * @return 指向已创建主题的指针。
     */
    virtual Topic* create_topic(const std::string& topic_name, const std::string& type_name, const TopicQos& qos, TopicListener* listener, const StatusMask& mask) = 0;

    /**
     * 删除现有主题。
     *
     * @param 要删除的主题。
     * @return 如果传递的主题为nullptr，则返回RETCODE_BAD_MEMETER；
     * 如果主题不属于此参与者或被任何实体引用，则返回RETCODE_PRECONDITIONNOT_MET；
     * 如果主题被删除，则返回RETCODE_OK。
     */
    virtual ReturnCode_t delete_topic(Topic*& topic) = 0;

    /**
     * 在此参与者中创建ContentFilteredTopic。
     *
     * @param name 内容筛选主题的名称。
     * @param related_topic 与订阅相关的主题。
     * @param filter_expression 创建筛选器的逻辑表达式。
     * @param expression_parameters 筛选内容的参数。
     * @return 指向创建的ContentFilteredTopic的指针。
     */
    virtual ContentFilteredTopic* create_contentfilteredtopic(const std::string& name, Topic* related_topic, const std::string& filter_expression, const StringSeq& expression_parameters) = 0;

    /**
     * 删除现有的ContentFilteredTopic。
     *
     * @param a_contentfilteredtopic 要删除的内容筛选主题。
     * @return 如果传递的主题为空ptr，则返回RETCODE_BAD_MEMETER；
     * 如果主题不属于此参与者或被任何实体引用，则返回RETCODE_PRECONDITIONNOT_MET；
     * 如果删除了ContentFilteredTopic，则返回RETCODE_OK。
     */
    virtual ReturnCode_t delete_contentfilteredtopic(ContentFilteredTopic*& contentfilteredtopic) = 0;

    /**
      * 在此参与者中创建多主题。
      *
      * @param name 多主题名称。
      * @param type_name 多主题的结果类型。
      * @param subscription_expression 组合过滤器的逻辑表达式。
      * @param expression_parameters 订阅内容的参数。
      * @return 指向创建的ContentFilteredTopic的指针，在错误情况下为nullptr。
      */
    virtual MultiTopic* create_multitopic(const std::string& name, const std::string& type_name, const std::string& subscription_expression, const StringSeq& expression_parameters) = 0;

    /**
     * 删除现有的多主题。
     *
     * @param a_multitopic 要删除的多主题。
     * @return 如果传递的主题为nullptr，则返回RETCODE_BAD_MEMETER；
     * 如果主题不属于此参与者或被任何实体引用，则返回RETCODE_PRECONDITIONNOT_MET；
     * 如果主题被删除，则返回RETCODE_OK。
     */
    virtual ReturnCode_t delete_multitopic(MultiTopic*& multitopic) = 0;

    /**
     * 允许访问已启用（或准备启用）的主题。
     * 通过此方法获得的主题必须被delete_topic销毁。
     *
     * @param topic_name 要获取的主题的主题名。
     * @param timeout 等待主题的最长时间。
     * @return 指向现有主题的指针，在错误情况下为nullptr。
     */
    virtual Topic* find_topic(const std::string& topic_name, const Duration_t& timeout) = 0;

    /**
     * 允许访问已启用（或准备启用）的主题。
     * 通过此方法获得的主题必须被delete_topic销毁。
     *
     * @param topic_name 要获取的主题的主题名。
     * @param timeout 等待主题的最长时间。
     * @return 指向现有主题的指针，在错误情况下为nullptr。
     */
    virtual TopicDescription* lookup_topicdescription(const std::string& name) const = 0;

    /**
     * 允许访问内置订阅者。
     *
     * @return 指向内置订阅者的指针，在错误情况下为nullptr
     */
    virtual const Subscriber* get_builtin_subscriber() const = 0;

    /**
     * 在本地忽略一个远程域参与者。
     *
     * @note 此函数不需要是可逆的。
     *
     * @param handle 要忽略的远程参与者的标识符。
     * @return 如果一切正常，返回RETCODE_OK代码，否则返回错误代码。
     */
    virtual ReturnCode_t ignore_participant(const InstanceHandle_t& handle) = 0;

    /**
     * 在本地忽略一个主题。
     *
     * @note 此函数不需要是可逆的。
     *
     * @param handle 要忽略的主题的标识符。
     * @return 如果一切正常，返回RETCODE_OK代码，否则返回错误代码。
     */
    virtual ReturnCode_t ignore_topic(const InstanceHandle_t& handle) = 0;

    /**
     * 在本地忽略数据写者。
     *
     * @note 此函数不需要是可逆的。
     *
     * @param handle 要忽略的数据写者的标识符
     * @return 如果一切正常，返回RETCODE_OK代码，否则返回错误代码。
     */
    virtual ReturnCode_t ignore_publication(const InstanceHandle_t& handle) = 0;

    /**
     * 在本地忽略数据读者。
     *
     * @note 此函数不需要是可逆的。
     *
     * @param handle 要忽略的数据读者的标识符
     * @return 如果一切正常，返回RETCODE_OK代码，否则返回错误代码。
     */
    virtual ReturnCode_t ignore_subscription(const InstanceHandle_t& handle) = 0;

    /**
     *此函数检索用于创建DomainParticipant的domain_id。
     *domain_id为标识DomainParticipant所属的DDS域。
     *
     *@return 参与者的domain_id。
     */
    virtual DomainId_t get_domain_id() const = 0;

    /**
     *删除通过“create”方法创建的所有实体
     *
     *@return 如果一切正常，返回RETCODE_OK代码，否则返回错误代码
     */
    virtual ReturnCode_t delete_contained_entities() = 0;

    /**
     * 此函数手动声明DomainParticipant的活力。
     * 这与LIVELINESS QoS策略结合使用，向LIVELINESS服务标示实体正保持活跃。
     *
     * 仅当DomainParticipant包含DataWriter实体时，才需要使用此函数
     * LIVELINESS设置为MANUAL_BY_PARTICIPANT，它只影响这些DataWriter实体的活跃度。
     * 否则，它没有任何效果。
     *
     * @note 通过DataWriter上的数据发送函数发送数据，可以保证DataWriter本身及其DomainParticipant的活力。
     * 因此，只有当应用程序没有定期发送数据时，才需要使用assert_liveliness。
     *
     * @return 如果liveliness激活成功返回RETCODE_OK, 否则返回RETCODE_ERROR.
     */
    virtual ReturnCode_t assert_liveliness() = 0;

    /**
     * 此函数设置发布者的QoS策略的默认值，
     * 在create_Publisher函数中默认QoS策略的情况下，
     * 该值将用于新创建的发布者实体。
     *
     * 此函数将检查生成的策略是否自洽；
     * 如果不是，则函数将无效并返回false。
     *
     * 可以将特殊值PUBLISHER_QOS_DEFAULT传递给此函数，
     * 以指示默认QOS应重置回工厂将使用的初始值，
     * 即如果从未调用set_default_publisher_qos函数时将使用的值。
     *
     * @param qos 待设置的PublisherQos
     * @return 如果Qos不是自一致的，则返回RETCODE_INCONSISTENT_POLICY；
     * 如果Qos正确更改，则返回RETCODE_OK。
     */
    virtual ReturnCode_t set_default_publisher_qos(const PublisherQos& qos) = 0;

    /**
     * 此函数检索发布者QoS的默认值，
     * 即在create_publisher函数中默认QoS策略的情况下，
     * 将用于新创建的发布服务器实体的QoS策略。
     *
     * 检索到的get_default_publisher_qos值将与上次成功调用
     * set_default_ppublisher_qos时指定的值集匹配，
     * 否则，如果从未进行过调用，则使用默认值。
     *
     * @param qos 返回default_publisher_qos的PublisherQos引用
     * @return RETCODE_OK
     */
    virtual ReturnCode_t get_default_publisher_qos(PublisherQos& qos) const = 0;

    /**
     * 此函数设置将用于新创建的订阅服务器QoS策略的默认值
     * 在create_subscriber函数中默认QoS策略的情况下的订阅者实体。
     *
     * 此函数将检查生成的策略是否自洽；如果不是，则函数将无效并返回false。
     *
     * 可以将特殊值SUBSCRIBER_QOS_DEFAULT传递给此函数，
     * 以指示默认QOS应重置回工厂将使用的初始值，
     * 即如果从未调用set_default_subscriber_qos函数时将使用的值。
     *
     * @param qos 要设置的订阅者QoS
     * @return 如果Qos不是自一致的，则返回RETCODE_INCONSISTENT_POLICY；
     * 如果Qos正确更改，则返回RETCODE_OK。
     */
    virtual ReturnCode_t set_default_subscriber_qos(const SubscriberQos& qos) = 0;

    /**
     * 此函数检索订阅者QoS的默认值，
     * 即在create_subscriber函数中默认QoS策略的情况下，
     * 将用于新创建的发布服务器实体的QoS策略。
     *
     * 检索到的get_default_subscriber_qos值将与上次成功调用
     * set_default_subscriber_qos时指定的值集匹配，
     * 否则，如果从未进行过调用，则使用默认值。
     *
     * @param qos 返回default_subscriber_qos的SubscriberQos引用
     * @return RETCODE_OK
     */
    virtual ReturnCode_t get_default_subscriber_qos(SubscriberQos& qos) const = 0;

    /**
     * 此函数设置Topic QoS策略的默认值，
     * 在create_topic函数中默认QoS策略的情况下，
     * 该默认值将用于新创建的Topic实体。
     *
     * 此函数将检查生成的策略是否自洽；如果不是，函数将无效，并返回RETCODE_INCONSISTENT_POLICY。
     *
     * 可以将特殊值TOPIC_QOS_DEFAULT传递给此函数，
     * 以指示默认QOS应重置回工厂将使用的初始值，
     * 即如果从未调用set_default_topic_qos函数时将使用的值。
     *
     * @param qos 要设置的TopicQos
     * @return 如果Qos不是自一致的，则返回RETCODE_INCONSISTENT_POLICY；
     * 如果Qos正确更改，则返回RETCODE_OK。
     */
    virtual ReturnCode_t set_default_topic_qos(const TopicQos& qos) = 0;

    /**
     * 此函数检索主题QoS的默认值，即将使用的QoS策略
     * 在create_topic函数中默认QoS策略的情况下，用于新创建的Topic实体。
     *
     * 检索到的get_default_topic_qos值将与上次成功调用
     * set_default_tpic_qos时指定的值集匹配，
     * 否则，如果从未进行过调用，则与TOPIC_QOS_DEFAULT匹配。
     *
     * @param qos 返回default_topic_qos的TopicQos引用
     * @return RETCODE_OK
     */
    virtual ReturnCode_t get_default_topic_qos(TopicQos& qos) const = 0;

    /**
     * 检索在域中发现且未被“忽略”的DomainParticits列表。
     *
     * @param[out]  participant_handles 指向将返回已发现参与者的向量。
     * @return 如果一切正常返回RETCODE_OK，否则返回错误代码。
     */
    virtual ReturnCode_t get_discovered_participants(InstanceHandleSeq& participant_handles) const = 0;

    /**
     * 检索已发现的未被忽略的参与者的DomainParticipant数据。
     *
     * @param[out]  participant_data 引用ParticipantBiltinTopicData对象以返回数据。
     * @param participant_handle DomainParticipant的InstanceHandle，用于从中检索数据。
     * @return 如果一切正常，则返回RETCODE_OK，如果参与者不存在，则返回PRECONDITION_NOT_MET。
     */
    virtual ReturnCode_t get_discovered_participant_data(ParticipantBuiltinTopicData& participant_data, const InstanceHandle_t& participant_handle) const = 0;

    /**
     * 检索在域中发现且未被“忽略”的主题列表。
     *
     * @param[out]  topic_handles 指向返回已发现主题的向量。
     * @return 如果一切正常RETCODE_OK，则返回错误代码。
     */
    virtual ReturnCode_t get_discovered_topics(InstanceHandleSeq& topic_handles) const = 0;

    /**
     * 检索已发现的未忽略主题的主题数据。
     *
     * @param[out]  topic_data 引用TopicBuiltinTopicData对象以返回数据。
     * @param topic_handle 用于从中检索数据的Topic的InstanceHandle。
     * @return 如果一切正常，则返回RETCODE_OK，如果主题不存在，则返回PRECONDITION_NOT_MET
     */
    virtual ReturnCode_t get_discovered_topic_data(TopicBuiltinTopicData& topic_data, const InstanceHandle_t& topic_handle) const = 0;

	/* 获取已发现的DataWriter列表 */
	virtual ReturnCode_t get_publications(InstanceHandleSeq& publication_handles, bool include_contained_entities) const = 0;

	/* 获取指定的DataWriter信息 */
	virtual ReturnCode_t get_publication_data(struct PublicationBuiltinTopicData& publication_data, const InstanceHandle_t& publication_handle) const = 0;

	/* 获取已发现的DataReader列表 */
	virtual ReturnCode_t get_subscriptions(InstanceHandleSeq& subscription_handles, bool include_contained_entities) const = 0;

	/* 获取指定的DataReader信息 */
	virtual ReturnCode_t get_subscription_data(struct SubscriptionBuiltinTopicData& subscription_data, const InstanceHandle_t& subscription_handle) const = 0;

	/**
	* 此函数检查给定的句柄是否表示从DomainParticipant创建的实体。
	*
	* @param a_handle 要查找的实体的InstanceHandle。
	* @return 如果包含实体，则为True。否则为False。
	*/
    virtual bool contains_entity(const InstanceHandle_t& handle) const = 0;

    /**
     * 此函数返回服务用于对数据写入进行时间戳并为其接收到的数据更新设置接收时间戳的当前时间值。
     *
     * @param current_time Time_t 返回当前时间的Time_t引用。
     * @return RETCODE_OK
     */
	static ReturnCode_t get_current_time(Time_t& current_time);

    /**
     * 在此参与者中注册一个类型。
     *
     * @param typeSupport 类型支持。
     * @param type_name 用于标识类型的名称。
     * @return 如果名称的大小为0，则返回RETCODE_BAD_MATER；
     * 如果存在另一个同名的TypeSupport，则返回RCODE_PRECONDITION_NOT_MET；
     * 如果已正确注册，则返回RETCODE_OK。
     */
	virtual ReturnCode_t registe_type(const std::string& typeName, TypeSupport* typeSupport) = 0;
#ifdef _XML_INTERFACE_CPP

    /**
     * @brief   指定QoS仓库的Qos配置，并创建发布者。
     * 
     * @param library_name QoS库的名字，允许为NULL，将转换为空字符串。
     * @param profile_name QoS配置名称，允许为NULL，转化为空字符串。
     * @param qos_name QoS名称，允许为NULL，转化为空字符串。
     * @param listener 发布者监听器。
     * @param mask 设置应用程序感兴趣的状态，只有应用程序感兴趣的状态发生变化时，才会通知应用程序。
     * 
     * @return 创建成功返回发布者指针，否则返回NULL。
     */
    virtual Publisher* create_publisher_with_qos_profile(
        const char* library_name, 
        const char* profile_name, 
        const char* qos_name, 
        PublisherListener* listener, 
        StatusMask mask) = 0;

    /**
     * @brief 指定Qos仓库中的Qos设置为默认发布者Qos。
     * 
     * @param library_name QoS库的名字，允许为NULL，将转换为空字符串。
     * @param profile_name QoS配置名称，允许为NULL，转化为空字符串。
     * @param qos_name QoS名称，允许为NULL，转化为空字符串。
     * 
     * @return 设置成功返回DDS_RETCODE_OK，否则返回DDS_RETCODE_ERROR。
     */
    virtual ReturnCode_t set_default_publisher_qos_with_profile(
        const char* library_name, 
        const char* profile_name, 
        const char* qos_name) = 0;
    
    /**
     * @brief   指定QoS仓库的Qos配置，并创建订阅者。
     * 
     * @param library_name QoS库的名字，允许为NULL，将转换为空字符串。
     * @param profile_name QoS配置名称，允许为NULL，转化为空字符串。
     * @param qos_name QoS名称，允许为NULL，转化为空字符串。
     * @param listener 订阅者监听器。
     * @param mask 设置应用程序感兴趣的状态，只有应用程序感兴趣的状态发生变化时，才会通知应用程序。
     * 
     * @return 创建成功返回订阅者指针，否则返回NULL。
     */
    virtual Subscriber* create_subscriber_with_qos_profile(
        const char* library_name, 
        const char* profile_name, 
        const char* qos_name, 
        SubscriberListener* listener, 
        StatusMask mask) = 0;

    /**
     * @brief 指定Qos仓库中的Qos设置为默认订阅Qos。
     * 
     * @param library_name QoS库的名字，允许为NULL，将转换为空字符串。
     * @param profile_name QoS配置名称，允许为NULL，转化为空字符串。
     * @param qos_name QoS名称，允许为NULL，转化为空字符串。
     * 
     * @return 设置成功返回DDS_RETCODE_OK，否则返回DDS_RETCODE_ERROR。
     */
    virtual ReturnCode_t set_default_subscriber_qos_with_profile(
        const char* library_name, 
        const char* profile_name, 
        const char* qos_name) = 0;
    
    /**
     * @brief   指定QoS仓库的Qos配置，并创建主题。
     * 
     * @param topic_name 主题名称。
     * @param type_name 类型名称。
     * @param library_name QoS库的名字，允许为NULL，将转换为空字符串。
     * @param profile_name QoS配置名称，允许为NULL，转化为空字符串。
     * @param qos_name QoS名称，允许为NULL，转化为空字符串。
     * @param listener 主题监听器。
     * @param mask 设置应用程序感兴趣的状态，只有应用程序感兴趣的状态发生变化时，才会通知应用程序。
     * 
     * @return 创建成功返回主题指针，否则返回NULL。
     */
    virtual Topic* create_topic_with_qos_profile(
        const std::string& topic_name,
        const std::string& type_name,
        const char* library_name, 
        const char* profile_name, 
        const char* qos_name, 
        TopicListener* listener, 
        StatusMask mask) = 0;

    /**
     * @brief 指定Qos仓库中的Qos设置为默认发布者Qos。
     * 
     * @param library_name QoS库的名字，允许为NULL，将转换为空字符串。
     * @param profile_name QoS配置名称，允许为NULL，转化为空字符串。
     * @param qos_name QoS名称，允许为NULL，转化为空字符串。
     * 
     * @return 设置成功返回DDS_RETCODE_OK，否则返回DDS_RETCODE_ERROR。
     */
    virtual ReturnCode_t set_default_topic_qos_with_profile(
        const char* library_name, 
        const char* profile_name, 
        const char* qos_name) = 0;
    
    /**
     * @brief   设置QoS为QoS仓库中指定Qos配置。
     * 
     * @param library_name QoS库的名字，允许为NULL，将转换为空字符串。
     * @param profile_name QoS配置名称，允许为NULL，转化为空字符串。
     * @param qos_name QoS名称，允许为NULL，转化为空字符串。
     * 
     * @return 设置成功返回DDS_RETCODE_OK，否则返回DDS_RETCODE_ERROR。
     */
    virtual ReturnCode_t set_qos_with_profile(
        const char* library_name, 
        const char* profile_name, 
        const char* qos_name) = 0;
        
#endif // _XML_INTERFACE_CPP
};

AGIDDS_NAMESPACE_END

#endif // !AGIDDS_DCPS_DOMAIN_DOMAINPARTICIPANT_H
